package com.ligg.socketservice.socket;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ligg.socketservice.pojo.ChatMessage;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author Ligg
 * @Time 2025/10/18
 **/
@Component
@ServerEndpoint("/chat/{username}")
@Slf4j
public class ChatEndpoint {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    private static final ConcurrentHashMap<String, Session> onlineUsers = new ConcurrentHashMap<>();
    private String username;

    /**
     * 用户链接
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("username") String username) throws IOException {
        this.username = username;
        onlineUsers.put(username, session);
        log.info("用户{}上线了", username);

        //广播消息给所有人：系统消息 + 更新用户列表
        broadcast(buildSystemMessage("用户" + username + "已上线"));
        broadcastUsers();
    }

    /**
     * 接收到消息
     */
    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        ChatMessage chatMessage = objectMapper.readValue(message, ChatMessage.class);
        chatMessage.setFrom(username);
        chatMessage.setType("chat");

        if ("ALL".equals(chatMessage.getTo())) {
            broadcast(objectMapper.writeValueAsString(chatMessage));//// 群聊
        } else {
            // 私聊
            Session toSession = onlineUsers.get(chatMessage.getTo());
            if (toSession != null && toSession.isOpen()) {
                toSession.getBasicRemote().sendText(objectMapper.writeValueAsString(chatMessage));
            }
            session.getBasicRemote().sendText(objectMapper.writeValueAsString(chatMessage));
        }
    }

    @OnClose
    public void onClose() {
        try {
            onlineUsers.remove(username);
            broadcast(buildSystemMessage("用户" + username + "已下线"));
            broadcastUsers();
        } catch (Exception e) {
            log.error("用户{}下线异常", username, e);
        }
    }

    @OnError
    public void onError(Throwable error) {
        log.error("用户{}异常", username, error);
    }


    // 构造系统消息
    private String buildSystemMessage(String text) throws IOException {
        ChatMessage msg = new ChatMessage();
        msg.setType("system");
        msg.setContent(text);
        return objectMapper.writeValueAsString(msg);
    }

    // 广播消息给所有用户
    private void broadcast(String message) throws IOException {
        for (Session s : onlineUsers.values()) {
            if (s.isOpen()) {
                s.getBasicRemote().sendText(message);
            }
        }
    }

    // 广播在线用户列表
    private void broadcastUsers() throws IOException {
        ChatMessage message = new ChatMessage();
        message.setType("users");
        message.setUsers(new ArrayList<>(onlineUsers.keySet()));
        broadcast(objectMapper.writeValueAsString(message));
    }
}
